package com.broada.apm.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.broada.apm.ajax.AlertResult;
import com.broada.apm.base.BaseService;
import com.broada.apm.entity.Alarm;
import com.broada.apm.entity.AlertSeverity;
import com.broada.apm.model.PagingList;
import com.broada.apm.model.Threshold;
import com.broada.apm.model.ThresholdParam;
import com.broada.apm.service.AlarmService;

public class AlarmServiceImpl extends BaseService implements AlarmService {
	private static Logger LOG = LoggerFactory.getLogger(AlarmServiceImpl.class);

	@Override
	public AlertResult queryLatestAlarmByType(String appId, String id, String type, int rows, String keyWord, String panelId, long startDate, long endDate) {
		AlertResult result = new AlertResult();
		List<Alarm> alerts = null;
		if (StringUtils.isBlank(id)) {
			alerts = new ArrayList<Alarm>();
		} else {
			// id为节点id，serviceId, 或资源id，resourceId, type为service或resource
			alerts = alertLogic.queryAlertByType(appId, id, type, rows, keyWord, panelId, new Date(startDate), new Date(endDate), 0);
		}
		result.setAlerts(alerts);
		return result;
	}

	@Override
	public AlertResult queryAlarms(int severity, String type, Long firstTime, Long lastTime, String source, int status,
			int clearStatus, String key, String sortField, String sortBy, int pageIndex, int pageSize) {
		AlertResult result = new AlertResult();
		try {
			Date startDate = new Date();
			Date endtDate = new Date();
			if (firstTime != null)
				startDate.setTime(firstTime);
			if (lastTime != null)
				endtDate.setTime(lastTime);
			PagingList<Alarm> serList = alertLogic.queryAlert(severity, type, startDate, endtDate, source, status,
					clearStatus, key, sortField, sortBy, pageIndex, pageSize);
			if (serList != null)
				result.addPagingList(serList);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			result.setFailMessage(e.getMessage());
			return result;
		}
		return result;
	}

	@Override
	public AlertResult queryAlertServerity() {
		AlertResult result = new AlertResult();
		try {
			List<AlertSeverity> serList = alertLogic.queryAlertSeverity();
			result.setAlarmRank(serList);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			return result;
		}
		return result;
	}

	@Override
	public AlertResult queryAlertStaticBySeverity() {
		AlertResult result = new AlertResult();
		try {
			List<Map<String, Object>> list = alertLogic.queryAlertStaticBySeverity();
			result.setSerRankNums(list);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			return result;
		}
		return result;
	}

	@Override
	public AlertResult delAlarms(String alarmIds) {
		AlertResult result = new AlertResult();
		try {
			String[] alarmArray = alarmIds.replace("\"", "").split(",");
			if (alarmArray.length > 0) {
				alertLogic.deleteAlertById(alarmArray);
			}
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			return result;
		}
		return result;
	}

	@Override
	public AlertResult updAlarms(HashMap<String, String> alarmIds) {
		AlertResult result = new AlertResult();
		String[] str = null;
		try {
			if (alarmIds.get("alarmIds").contains(",")) {
				str = alarmIds.get("alarmIds").split(",");
			} else {
				str = new String[1];
				str[0] = alarmIds.get("alarmIds");
			}
			int status = Integer.parseInt(alarmIds.get("status"));
			if (str.length > 0) {
				alertLogic.updateAlertStatus(status, str);
			}
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			LOG.debug("修改告警状态失败", e);
			return result;
		}
		return result;
	}

	@Override
	public AlertResult queryAlertCountByWorstSeverity() {
		AlertResult result = new AlertResult();
		int alertCountByWorstSeverity =  alertLogic.queryAlertCountByWorstSeverity();
		result.setAlertCountByWorstSeverity(alertCountByWorstSeverity);
		return result;
	}

	@Override
	public AlertResult saveThreshold(String appId, Threshold threshold, String panelId) {
		AlertResult result = new AlertResult();
		// 首先判断阈值的类型，普通告警阈值需要判断另一种模式下是否已有阈值，如果有则需要一起保存
		if ("threshold".equals(threshold.getThresholdType())) {
			if (threshold.getThresholdParam().length == 0) { // 如果保存的阈值为空，则直接返回
				return result;
			}
			com.broada.apm.entity.Threshold exist = alertLogic.queryThresholdByTargetId(appId, threshold.getTargetId(), threshold.getThresholdType(), null);
			if (exist != null) { // 保存另一种模式下的阈值
				ThresholdParam[] thresholdParam = new ThresholdParam[exist.getThresholdParam().length + threshold.getThresholdParam().length];
				for (int i = 0; i < thresholdParam.length; i++) {
					if (i < exist.getThresholdParam().length) {
						thresholdParam[i] = exist.getThresholdParam()[i];
					} else {
						thresholdParam[i] = threshold.getThresholdParam()[thresholdParam.length - i - 1];
					}
				}
				threshold.setThresholdParam(thresholdParam);
				threshold.setAppId(appId);
				if (!alertLogic.deleteThresholdsByTargetId(appId, threshold.getTargetId(), threshold.getThresholdType(), null)) {
					result.setFailMessage("告警配置阀值删除失败.");
					return result;
				}
			}
			threshold.setStatus("on");
//			setValidTime(threshold);
			if (!alertLogic.saveThreshold(appId, threshold, null))
				result.setFailMessage("阀值配置保存失败...");
			// 保存普通告警阈值，需要把基线阈值关闭
			if (!alertLogic.deleteThresholdsByTargetId(appId, threshold.getTargetId(), "algorithm", panelId)) {
				result.setFailMessage("基线告警配置阀值删除失败.");
				return result;
			}
		} else {
			com.broada.apm.entity.Threshold exist = alertLogic.queryThresholdByTargetId(appId, threshold.getTargetId(), threshold.getThresholdType(), panelId);
			if (exist != null ) {
				result.setFailMessage("基线阈值已存在.");
				return result;
			}
//			setValidTime(threshold);
			threshold.setStatus("on");
			threshold.setAppId(appId);
			threshold.setPanelId(panelId);
			if (!alertLogic.saveThreshold(appId, threshold, panelId))
				result.setFailMessage("基线阀值配置保存失败...");
			
		    exist = null;
			exist = alertLogic.queryThresholdByTargetId(appId, threshold.getTargetId(), "threshold", null);
			if (exist != null) { // 保存另一种模式下的阈值
				if (!alertLogic.deleteThresholdsByTargetId(appId, threshold.getTargetId(), "threshold", null)) {
					result.setFailMessage("告警配置阀值删除失败.");
					return result;
				}
				List<ThresholdParam> paramList = new ArrayList<ThresholdParam>();
				for (ThresholdParam param : exist.getThresholdParam()) {
					if ((param.getIndicator().startsWith("b") && "business".equals(panelId))
							|| (!param.getIndicator().startsWith("b") && "system".equals(panelId))) {
						continue;
					}
					paramList.add(param);
				}
				if (!paramList.isEmpty()) {
					ThresholdParam[] thresholdParam = new ThresholdParam[paramList.size()];
					for (int i=0; i<paramList.size(); i++) {
						thresholdParam[i] = paramList.get(i);
					}
					threshold.setThresholdParam(thresholdParam);
					threshold.setPanelId(exist.getPanelId());
					threshold.setStatus("on");
					threshold.setTargetId(exist.getTargetId());
//					threshold.setValidTime(exist.getValidTime());
					threshold.setThresholdType("threshold");
					if (!alertLogic.saveThreshold(appId, threshold, null)) {
						result.setFailMessage("阀值配置保存失败...");
					}
				}
			}
		}
		return result;
	}

	@Override
	public AlertResult queryThresholdByTargetId(String appId, String targetId, String panelId) {
		AlertResult result = new AlertResult();
		com.broada.apm.entity.Threshold threshold = alertLogic.queryThresholdByTargetId(appId, targetId, "algorithm", panelId);
		if (threshold == null) {
			threshold = alertLogic.queryThresholdByTargetId(appId, targetId, "threshold", null);
		}
		result.setThreshold(threshold);
		return result;
	}

	@Override
	public AlertResult queryThresholdsByApplicationId(String appId, String panelId) {
		AlertResult result = new AlertResult();
		List<com.broada.apm.entity.Threshold> thresholds = alertLogic.queryThresholdsByApplicationId(appId, panelId);
		result.setThresholds(thresholds);
		return result;
	}

	@Override
	public AlertResult deleteThresholdsByTargetId(String appId, String targetId, String panelId, String thresholdType) {
		AlertResult result = new AlertResult();
		if ("threshold".equals(thresholdType)) {// 普通告警阈值删除需要区分是交易模式下还是非交易模式下
			com.broada.apm.entity.Threshold thresholdData = alertLogic.queryThresholdByTargetId(appId, targetId, thresholdType, null);
			List<ThresholdParam> paramList = new ArrayList<ThresholdParam>();
			for (ThresholdParam param : thresholdData.getThresholdParam()) {
				if ((param.getIndicator().startsWith("b") && "business".equals(panelId)) || (!param.getIndicator().startsWith("b") && "system".equals(panelId))) {
					continue;
				}
				paramList.add(param);
			}
			if (paramList.isEmpty()) {
				if (!alertLogic.deleteThresholdsByTargetId(appId, targetId, thresholdType, panelId))
					result.setFailMessage("告警配置阀值删除失败.");
			} else {
				ThresholdParam[] thresholdParam = new ThresholdParam[paramList.size()];
				for (int i=0; i<paramList.size(); i++) {
					thresholdParam[i] = paramList.get(i);
				}
				thresholdData.setThresholdParam(thresholdParam);
				
				if (!alertLogic.deleteThresholdsByTargetId(appId, targetId, thresholdType, panelId))
					result.setFailMessage("告警配置阀值删除失败.");
				
				Threshold threshold = new Threshold();
				threshold.setTargetId(thresholdData.getTargetId());
				threshold.setThresholdParam(thresholdParam);
				threshold.setThresholdType(thresholdData.getThresholdType());
				if (!alertLogic.saveThreshold(appId, threshold, panelId))
					result.setFailMessage("告警配置阀值更新失败.");
			}
		} else {
			if (!alertLogic.deleteThresholdsByTargetId(appId, targetId, thresholdType, panelId))
				result.setFailMessage("告警配置阀值删除失败.");
		}
		
		return result;
	}

	@Override
	public AlertResult updateThreshold(String appId, Threshold threshold, String panelId) {
		AlertResult result = new AlertResult();
		com.broada.apm.entity.Threshold thresholdData = alertLogic.queryThresholdByTargetId(appId, threshold.getTargetId(), "threshold", null);
		com.broada.apm.entity.Threshold algotithmData = alertLogic.queryThresholdByTargetId(appId, threshold.getTargetId(), "algorithm", panelId);
		if ("threshold".equals(threshold.getThresholdType())) {
			if (algotithmData != null && panelId.equals(algotithmData.getPanelId())) {
				if (!alertLogic.deleteThresholdsByTargetId(appId, threshold.getTargetId(), "algorithm", panelId)) {
					result.setFailMessage("基线告警配置阀值删除失败.");
					return result;
				}
			}
			List<ThresholdParam> paramList = new ArrayList<ThresholdParam>();
			if (thresholdData != null) {
				if (!"default".equals(panelId)) { // 服务节点不分交易模式与非交易模式
					for (ThresholdParam param : thresholdData.getThresholdParam()) {
						if ((param.getIndicator().startsWith("b") && "business".equals(panelId))
								|| (!param.getIndicator().startsWith("b") && "system".equals(panelId))) {
							continue;
						}
						paramList.add(param);
					}
					if (!paramList.isEmpty()) {
						ThresholdParam[] thresholdParam = new ThresholdParam[threshold.getThresholdParam().length + paramList.size()];
						for (int i = 0; i < threshold.getThresholdParam().length; i++) {
							thresholdParam[i] = threshold.getThresholdParam()[i];
						}
						for (int i = threshold.getThresholdParam().length; i < threshold.getThresholdParam().length + paramList.size(); i++) {
							thresholdParam[i] = paramList.get(i - threshold.getThresholdParam().length);
						}
						threshold.setThresholdParam(thresholdParam);
					}
				}
				if (threshold.getThresholdParam().length == 0) {
					if (!alertLogic.deleteThresholdsByTargetId(appId, threshold.getTargetId(), "threshold", null))
						result.setFailMessage("告警配置阀值删除失败.");
					return result;
				} 
			}
			threshold.setStatus("on");
//			setValidTime(threshold);
			if (!alertLogic.saveThreshold(appId, threshold, null))
				result.setFailMessage("告警配置阀值更新失败.");
		} else {
			List<ThresholdParam> paramList = new ArrayList<ThresholdParam>();
			if (thresholdData != null) {
				if (!"default".equals(panelId)) { // 服务节点不分交易模式与非交易模式
					for (ThresholdParam param : thresholdData.getThresholdParam()) {
						if ((param.getIndicator().startsWith("b") && "business".equals(panelId)) 
								|| (!param.getIndicator().startsWith("b") && "system".equals(panelId))) {
							continue;
						}
						paramList.add(param);
					}
					if (!paramList.isEmpty()) {
						ThresholdParam[] thresholdParam = new ThresholdParam[paramList.size()];
						for (int i = 0; i < paramList.size(); i++) {
							thresholdParam[i] = paramList.get(i);
						}
						thresholdData.setThresholdParam(thresholdParam);
					}
				}
				if (paramList.size() == 0) {
					if (!alertLogic.deleteThresholdsByTargetId(appId, threshold.getTargetId(), "threshold", null))
						result.setFailMessage("告警配置阀值删除失败.");
				} else {
					Threshold newThreshold = new Threshold();
					newThreshold.setAppId(appId);
					newThreshold.setStatus("on");
					newThreshold.setPanelId(panelId);
					newThreshold.setTargetId(thresholdData.getTargetId());
					newThreshold.setThresholdParam(thresholdData.getThresholdParam());
					newThreshold.setThresholdType(thresholdData.getThresholdType());
//					newThreshold.setValidTime(thresholdData.getValidTime());
					if (!alertLogic.saveThreshold(appId, newThreshold, null))
						result.setFailMessage("告警配置阀值更新失败.");
				}
			}
			threshold.setStatus("on");
			threshold.setAppId(appId);
			threshold.setPanelId(panelId);
//			setValidTime(threshold);
			if (!alertLogic.saveThreshold(appId, threshold, panelId))
				result.setFailMessage("告警配置阀值更新失败.");
		}
		return result;
	}

	@Override
	public AlertResult queryServerCountByWorstSeverity() {
		AlertResult result = new AlertResult();
		try {
			List<Map<String, Object>> list = alertLogic.queryServerCountBySeverity();
			result.setSerRankNums(list);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			result.setFailMessage("queryServerCountBySeverity告警等级个数统计失败");
		}
		return result;
	}
	
//	private void setValidTime(Threshold threshold) {
//		if (threshold.getValidTime() == null || threshold.getValidTime().isEmpty()) {
//			Map<String, String[]> validTime = new HashMap<String, String[]>();
//			validTime.put("1", new String[]{"00:00:00-24:00:00"});
//			validTime.put("2", new String[]{"00:00:00-24:00:00"});
//			validTime.put("3", new String[]{"00:00:00-24:00:00"});
//			validTime.put("4", new String[]{"00:00:00-24:00:00"});
//			validTime.put("5", new String[]{"00:00:00-24:00:00"});
//			validTime.put("6", new String[]{"00:00:00-24:00:00"});
//			validTime.put("7", new String[]{"00:00:00-24:00:00"});
//			threshold.setValidTime(validTime);
//		}
//	}
}
